package mrpanyu.guitool.base.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class Profiles {

	private static final String ENCODING = "UTF-8";

	private String toolName;
	private File saveFile;
	private Map<String, Profile> profiles = new TreeMap<String, Profile>();

	public Profiles(String toolName) {
		this.toolName = toolName;
		this.saveFile = new File(normalizeName(toolName) + ".profiles");
	}

	public String getToolName() {
		return toolName;
	}

	public Set<String> getProfileNames() {
		return profiles.keySet();
	}

	public Profile getProfile(String name) {
		return profiles.get(name);
	}

	public void setProfile(String name, Profile profile) {
		profiles.put(name, profile);
	}

	public void removeProfile(String name) {
		profiles.remove(name);
	}

	public void load() {
		load(saveFile);
	}

	public void save() {
		save(saveFile);
	}

	public void load(File f) {
		try {
			if (!f.exists()) {
				return;
			}
			List<String> lines = readLines(f);
			Profile profile = null;
			String lastParamName = null;
			for (String line : lines) {
				if (line != null && line.length() > 0) {
					if (line.startsWith("[")) {
						String name = line.substring(1, line.indexOf("]"));
						profile = new Profile(name);
						profiles.put(name, profile);
					} else if (line.startsWith("\t")) {
						String value = profile.getParameterValues().get(lastParamName);
						value = value + "\n" + line.substring(1);
						profile.getParameterValues().put(lastParamName, value);
					} else {
						String[] arr = line.split("=", 2);
						profile.getParameterValues().put(arr[0], arr[1]);
						lastParamName = arr[0];
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public void save(File f) {
		List<String> lines = new ArrayList<String>();
		for (Map.Entry<String, Profile> entry : profiles.entrySet()) {
			String name = entry.getKey();
			Profile profile = entry.getValue();
			lines.add("[" + name + "]");
			for (Map.Entry<String, String> e : profile.getParameterValues().entrySet()) {
				lines.add(e.getKey() + "=" + e.getValue().replace("\n", "\n\t"));
			}
			lines.add("");
		}
		try {
			writeLines(f, lines);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	private String normalizeName(String name) {
		String invalidChars = ":|\\/<>?*";
		for (char c : invalidChars.toCharArray()) {
			name = name.replace(c, '_');
		}
		return name;
	}

	private List<String> readLines(File f) throws IOException {
		try (FileInputStream fin = new FileInputStream(f);
				InputStreamReader r = new InputStreamReader(fin, ENCODING);
				BufferedReader reader = new BufferedReader(r)) {
			List<String> lines = new ArrayList<>();
			String line = reader.readLine();
			while (line != null) {
				lines.add(line);
				line = reader.readLine();
			}
			return lines;
		}
	}

	private void writeLines(File f, List<String> lines) throws IOException {
		try (FileOutputStream fout = new FileOutputStream(f);
				OutputStreamWriter w = new OutputStreamWriter(fout, ENCODING);
				PrintWriter writer = new PrintWriter(w)) {
			for (String line : lines) {
				writer.println(line);
			}
		}
	}
}
